#ifndef DISPLAYRECORDER_DISPLAYRECORDER_H
#define DISPLAYRECORDER_DISPLAYRECORDER_H

#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/ISurfaceComposer.h>
#include <media/MediaCodecBuffer.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaFormatPriv.h>
#include <media/NdkMediaMuxer.h>
#include <media/openmax/OMX_IVCommon.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <mediadrm/ICrypto.h>
#include <ui/DisplayConfig.h>
#include <ui/DisplayState.h>


using android::PhysicalDisplayId;
using android::IGraphicBufferProducer;
using android::status_t;
using android::sp;
using android::IBinder;
using android::MediaCodec;

namespace ui = android::ui;

class DisplayRecorder {

    typedef std::function<void(const char* fileName)> OnStart;
    typedef std::function<void()> OnFinish;
    typedef std::function<void(int errCode)> OnFail;

public:
    DisplayRecorder(PhysicalDisplayId displayId, std::string fileName, int duration);
    DisplayRecorder(PhysicalDisplayId displayId, std::string fileName);
    status_t start();
    status_t stop();

    void setCallback(DisplayRecorder::OnStart start, DisplayRecorder::OnFinish finish, DisplayRecorder::OnFail fail);

    void release();
    
    ~DisplayRecorder();

private:
    status_t setDisplayProjection(android::SurfaceComposerClient::Transaction& t,const sp<IBinder>& dpy,const ui::DisplayState& displayState);

    status_t prepareVirtualDisplay(const ui::DisplayState& displayState,const sp<IGraphicBufferProducer>& bufferProducer,sp<IBinder>* pDisplayHandle);

    status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec,sp<IGraphicBufferProducer>* pBufferProducer);

    status_t runEncoder(const sp<MediaCodec>& encoder, AMediaMuxer *muxer);

    static void ensureVideoFile(const std::string& fileName);

private:
    PhysicalDisplayId displayId;
    std::string filePath;
    int duration;

    //  窗口尺寸信息
    uint32_t gVideoWidth = 0;
    uint32_t gVideoHeight = 0;

    volatile bool gStopRequested = false;

    // Callback
    OnStart onStart;
    OnFinish onFinish;
    OnFail onFail;

private:
    const uint32_t gBitRate = 16000000;     // 16Mbps
    const uint32_t gDefaultDurationSec = 60; // seconds
    const char* kMimeTypeAvc = "video/avc";
    const char* kMimeTypeApplicationOctetstream = "application/octet-stream";

};

#endif /*DISPLAYRECORDER_DISPLAYRECORDER_H*/